import SvgEditor, { type MouseOptions } from "@svgedit/svgcanvas";

type ClientPos = {
  x: number;
  y: number;
}

const modeId = 'shapelib';

function init(svgEditor: SvgEditor) {

  const canv = svgEditor;
  const svgroot = canv.getSvgRoot();

  let lastBBox: SVGRect;
  const startClientPos: Partial<ClientPos> = {};

  let curShape: any;
  let startX: number;
  let startY: number;

  return {
    mouseDown(opts: MouseOptions) {
      const mode = canv.getMode();

      if (mode !== modeId) { 
        return;
      }

      const currentD = canv.shapeLibPath;
      startX = opts.start_x;
      const x = startX;
      startY = opts.start_y;
      const y = startY;
      const curStyle = canv.getStyle();

      startClientPos.x = opts.event.clientX;
      startClientPos.y = opts.event.clientY;

      curShape = canv.addSVGElementsFromJson({
        element: 'path',
        curStyles: true,
        attr: {
          d: currentD,
          id: canv.getNextId(),
          opacity: curStyle.opacity / 2,
          style: 'pointer-events:none'
        }
      });

      const transform = `translate(${x},${y}) scale(0.005) translate(${-x},${-y})`;
      curShape.setAttribute('transform', transform);
      canv.recalculateDimensions(curShape);

      lastBBox = curShape.getBBox();

      return {
        started: true
      }
    },
    mouseMove(opts: MouseOptions) {
      const mode = canv.getMode();

      if (mode !== modeId) { 
        return 
      }

      const zoom = canv.getZoom();
      const evt = opts.event;

      const x = opts.mouse_x / zoom
      const y = opts.mouse_y / zoom

      const tlist = curShape.transform.baseVal
      const box = curShape.getBBox()
      const left = box.x; const top = box.y

      const newbox = {
        x: Math.min(startX, x),
        y: Math.min(startY, y),
        width: Math.abs(x - startX),
        height: Math.abs(y - startY)
      }

      let sx = (newbox.width / lastBBox.width) || 1
      let sy = (newbox.height / lastBBox.height) || 1

      // Not perfect, but mostly works...
      let tx = 0
      if (x < startX) {
        tx = lastBBox.width
      }
      let ty = 0
      if (y < startY) {
        ty = lastBBox.height
      }

      // update the transform list with translate,scale,translate
      const translateOrigin = svgroot.createSVGTransform();
      const scale = svgroot.createSVGTransform();
      const translateBack = svgroot.createSVGTransform();

      translateOrigin.setTranslate(-(left + tx), -(top + ty));

      if (!evt.shiftKey) {
        const max = Math.min(Math.abs(sx), Math.abs(sy))

        sx = max * (sx < 0 ? -1 : 1)
        sy = max * (sy < 0 ? -1 : 1)
      }
      scale.setScale(sx, sy)

      translateBack.setTranslate(left + tx, top + ty);
      tlist.appendItem(translateBack);
      tlist.appendItem(scale);
      tlist.appendItem(translateOrigin);

      canv.recalculateDimensions(curShape);

      lastBBox = curShape.getBBox();
    },
    mouseUp(opts: MouseOptions) {
      const mode = canv.getMode();

      if (mode !== modeId) {
        return;
      }

      const keepObject = (
        opts.event.clientX !== startClientPos.x &&
        opts.event.clientY !== startClientPos.y
      );

      return {
        keep: keepObject,
        element: curShape,
        started: false
      }
    }
  }
}

export default init;